/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openFuyao is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

/*
Package helm include helm related struct
*/
package helm

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"

	"application-management-service/pkg/constant"
)

// ChartRepository CRD corresponding struct
type ChartRepository struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`

	// spec holds all the information that is needed for connect to helm repository
	// mainly referenced to helm.sh/helm/v3/pkg/repo.Entry
	Spec ChartRepositorySpec `json:"spec"`
}

// ChartRepositorySpec spec struct
type ChartRepositorySpec struct {
	// displayed name for the helm repository
	DisplayName string `json:"displayName"`
	// URL for the helm repository
	URL string `json:"url"`

	// BasicAuth is an optional reference to a secret type basic-auth
	// It is used for user validation
	// The key "username" is used to store usernam:153e
	// The key "password" is used to store password
	BasicAuth SecretReference `json:"basicAuth"`

	// TLS is an optional reference to a secret type tls
	// It is used for user validation
	// The key "tls.crt" is used to store the PEM-encoded certificate file
	// The key "tls.key" is used to store the private key
	TLS SecretReference `json:"tls"`

	// CA is an optional reference to a config map
	// It is used as a trust anchor to validate the TLS certificate presented by the remote server.
	// The key "ca-bundle.crt" is used to store the PEM-encoded CA bundle.
	CA ConfigMapReference `json:"ca"`

	// Skips the validity check for the server's certificate
	InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify"`

	// Pass credentials to all domains
	PassCredentialsAll bool `json:"passCredentialsAll"`
}

// SecretReference CRD secret reference
type SecretReference struct {
	// name is the metadata.name of the referenced secret
	Name string `json:"name"`
}

// ConfigMapReference CRD configmap reference
type ConfigMapReference struct {
	// name is the metadata.name of the referenced config map
	Name string `json:"name"`
}

// DeepCopyInto copies all properties of this object into another object of the same type.
func (in *ChartRepository) DeepCopyInto(out *ChartRepository) {
	*out = *in
	out.TypeMeta = in.TypeMeta
	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
	in.Spec.DeepCopyInto(&out.Spec)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChartRepository.
func (in *ChartRepository) DeepCopy() *ChartRepository {
	if in == nil {
		return nil
	}
	out := new(ChartRepository)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ChartRepository) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

// DeepCopyInto copies all properties of this object into another object of the same type.
func (in *ChartRepositorySpec) DeepCopyInto(out *ChartRepositorySpec) {
	*out = *in
	out.BasicAuth = in.BasicAuth
	out.TLS = in.TLS
	out.CA = in.CA
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChartRepositorySpec.
func (in *ChartRepositorySpec) DeepCopy() *ChartRepositorySpec {
	if in == nil {
		return nil
	}
	out := new(ChartRepositorySpec)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto copies all properties of this object into another object of the same type.
func (in *SecretReference) DeepCopyInto(out *SecretReference) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretReference.
func (in *SecretReference) DeepCopy() *SecretReference {
	if in == nil {
		return nil
	}
	out := new(SecretReference)
	in.DeepCopyInto(out)
	return out
}

// DeepCopyInto copies all properties of this object into another object of the same type.
func (in *ConfigMapReference) DeepCopyInto(out *ConfigMapReference) {
	*out = *in
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapReference.
func (in *ConfigMapReference) DeepCopy() *ConfigMapReference {
	if in == nil {
		return nil
	}
	out := new(ConfigMapReference)
	in.DeepCopyInto(out)
	return out
}

// AddHelmChartRepositoryToScheme  AddHelmChartRepositoryToScheme
func AddHelmChartRepositoryToScheme(scheme *runtime.Scheme) error {
	schemeBuilder := runtime.NewSchemeBuilder(addKnownTypes)
	return schemeBuilder.AddToScheme(scheme)
}

func addKnownTypes(scheme *runtime.Scheme) error {
	scheme.AddKnownTypes(schema.GroupVersion{
		Group:   constant.CRDRepoGroup,
		Version: constant.CRDRepoVersion,
	},
		&ChartRepository{},
	)
	metav1.AddToGroupVersion(scheme, schema.GroupVersion{
		Group:   constant.CRDRepoGroup,
		Version: constant.CRDRepoVersion,
	})
	return nil
}

// ChartRepositoryList list of CRD resources
type ChartRepositoryList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata,omitempty"`
	Items           []ChartRepository `json:"items"`
}

// SafeRepoEntry represents a collection of parameters for chart repository
// modified from "helm.sh/helm/v3/pkg/repo/Entry"
// change string username & password to []byte for security reason
type SafeRepoEntry struct {
	Name                  string `json:"name"`
	URL                   string `json:"url"`
	Username              []byte `json:"username"`
	Password              []byte `json:"password"`
	CertFile              string `json:"certFile"`
	KeyFile               string `json:"keyFile"`
	CAFile                string `json:"caFile"`
	InsecureSkipTLSVerify bool   `json:"insecure_skip_tls_verify"`
	PassCredentialsAll    bool   `json:"pass_credentials_all"`
}

// ApplicationManagementServiceConfig application-management-service config read from console service configmap.data
type ApplicationManagementServiceConfig struct {
	LocalHarborDisplayName    string   `json:"local-harbor-display-name"`
	LocalHarborHost           string   `json:"local-harbor-host"`
	LocalHarborProject        string   `json:"local-harbor-project"`
	OfficialHarborDisplayName string   `json:"official-harbor-display-name"`
	OfficialHarborHost        string   `json:"official-harbor-host"`
	OfficialHarborProject     string   `json:"official-harbor-project"`
	MarketplaceScenes         []string `json:"marketplace-scenes"`
	OAuthServerHost           string   `json:"oauth-server-host"`
	ConsoleServerHost         string   `json:"console-server-host"`
	ConsoleWebsiteHost        string   `json:"console-website-host"`
	AlertHost                 string   `json:"alert-host"`
	MonitoringHost            string   `json:"monitoring-host"`
	OfficialHarborTagsURL     string   `json:"official-harbor-tags-URL"`
	InsecureSkipVerify        string   `json:"insecure-skip-verify"`
	ServerName                string   `json:"server-name"`
	ChartLimit                string   `json:"chart-limit"`
	MarketPlaceServiceHost    string   `json:"marketplace-service-host"`
	HelmTimeout               string   `json:"helm-timeout"`
	HelmWaitCharts            []string `json:"helm-wait-charts"`
}

// OfficialTagsResponse /tags/list response from official harbor
type OfficialTagsResponse struct {
	Name         string   `json:"name"`
	TaggedCharts []string `json:"tags"`
}
